package la.iok.hzsvn.lewin.movie.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import la.iok.hzsvn.lewin.movie.config.RedisKey;
import la.iok.hzsvn.lewin.movie.core.Token;
import la.iok.hzsvn.lewin.movie.core.exception.ErrorCode;
import la.iok.hzsvn.lewin.movie.core.model.DeviceVo;
import la.iok.hzsvn.lewin.movie.services.MovieServiceInvoker;
import la.iok.hzsvn.redis.service.RedisService;
import la.iok.hzsvn.share.annotations.NotNull;
import la.iok.hzsvn.share.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class DeviceLocalMovieServiceImpl implements DeviceLocalMovieService{
    private static final Logger logger = LoggerFactory.getLogger(DeviceLocalMovieService.class);
    private final RedisService redisService;
    private final RedisKey redisKey;
    private final MovieServiceInvoker movieServiceInvoker;
    private final ObjectMapper objectMapper;

    public DeviceLocalMovieServiceImpl(RedisService redisService,
                                       RedisKey redisKey,
                                       MovieServiceInvoker movieServiceInvoker,
                                       ObjectMapper objectMapper) {
        this.redisService = redisService;
        this.redisKey = redisKey;
        this.movieServiceInvoker = movieServiceInvoker;
        this.objectMapper = objectMapper;
    }

    @Override
    public void updateMovieList(@NotNull Token token, Long[] movieIds) {
        if(token.getDeviceId() == null || movieIds == null){
            return;
        }
        DeviceVo device = movieServiceInvoker.deviceInfo(token.getDeviceId());
        ErrorCode.DEVICE_NOT_EXIST.assertNotNull(device,token.getDeviceId());
        try {
            String key = redisKey.deviceLocalMovieKey(device.getCode());
            redisService.set(key,objectMapper.writeValueAsString(Arrays.stream(movieIds).filter(Objects::nonNull).collect(Collectors.toList())));
            redisService.expire(key,7, TimeUnit.DAYS);  //7天有效期
        } catch (JsonProcessingException e) {
            logger.error("剧本列表json序列化失败:{}-{}",device.getId(),device.getCode(),e);
        }
    }

    @Override
    public Long[] loadMovieList(@NotNull String code){
        if(StringUtils.isBlank(code)){
            return null;
        }
        String key = redisKey.deviceLocalMovieKey(code);
        String value = (String) redisService.get(key);
        if(StringUtils.isBlank(value)){
            return null;
        }
        try {
            return objectMapper.readValue(value,Long[].class);
        } catch (JsonProcessingException e) {
            logger.error("剧本列表反序列化失败",e);
            return null;
        }
    }

    @Override
    public void remove(String code) {
        redisService.expire(redisKey.deviceLocalMovieKey(code),0,TimeUnit.DAYS);
    }
}
